package com.content.scaffold.controller.auth;

import cn.hutool.core.util.BooleanUtil;
import com.content.scaffold.common.constants.ConfigConstant;
import com.content.scaffold.common.identity.IdGenerator;
import com.content.scaffold.common.utils.PasswordUtils;
import com.content.scaffold.common.utils.RSAUtils;
import com.content.scaffold.common.web.RequestContext;
import com.content.scaffold.common.web.ResultBody;
import com.content.scaffold.model.dto.login.LoginDto;
import com.content.scaffold.model.dto.login.LoginUser;
import com.content.scaffold.model.dto.login.UserInfo;
import com.content.scaffold.model.entity.SysUser;
import com.content.scaffold.model.enums.LoginErrorMsg;
import com.content.scaffold.model.mp.UserConvert;
import com.content.scaffold.service.sys.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * 登陆api接口
 * @author xiaojl
 */
@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("api")
public class LoginController {

    final private SysUserService sysUserService;
    final private IdGenerator idGenerator;

    /**
     * 登陆接口
     *
     * @param loginDto 登陆
     * @return LoginUser
     */
    @PostMapping("toLogin")
    public ResultBody<LoginUser> toLogin(@RequestBody @Validated LoginDto loginDto) {
        try {
            String password = decryptPassword(loginDto.getPassword());
            if (password == null) {
                return ResultBody.error(LoginErrorMsg.PASSWORD_DECRYPT_FAIL);
            }
            LoginUser loginUser =  new LoginUser();
            SysUser sysUser = sysUserService.queryLoginUser(loginDto);
            if (sysUser == null) {
                log.warn("登录失败，用户不存在或密码错误，用户名: {}", loginDto.getUserCode());
                return ResultBody.error(LoginErrorMsg.LOGIN_FAILED);
            }

            boolean b = PasswordUtils.checkpw(password, PasswordUtils.hashpw(password));
            if (BooleanUtil.isTrue(b)){
                UserInfo map = UserConvert.INSTANCE.map(sysUser);
                loginUser.setUserInfo(map);
                loginUser.setToken(idGenerator.nextStringId());
                setRequestContext(loginUser);
            }


            return ResultBody.ok(loginUser);
        } catch (IllegalArgumentException | IllegalStateException e) {
            log.error("登录过程中发生非法参数或状态异常，用户名: {}", loginDto.getUserCode(), e);
            return ResultBody.error(LoginErrorMsg.LOGIN_FAILED);
        } catch (Exception e) {
            log.error("登录过程中发生未知异常，用户名: {}", loginDto.getUserCode(), e);
            return ResultBody.error(e.getMessage());
        }
    }

    private String decryptPassword(String encryptedPassword) {
        try {
            return RSAUtils.decrypt(encryptedPassword, ConfigConstant.PRIVATE_KEY);
        } catch (Exception e) {
            log.warn("密码解密失败，原因: {}", e.getMessage());
            return null;
        }
    }

    private void setRequestContext(LoginUser loginUser) {
        RequestContext.buildRequestInfo(loginUser);
        RequestContext.putLoginUser(loginUser);
    }
}
